package edu.pku.hawk.cloud;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

import edu.pku.hawk.cloud.model.HistoryData;
import edu.pku.ss.taas.cloud.monitor.lightweight.Constants;
import edu.pku.ss.taas.cloud.monitor.lightweight.MonitorClientManager;
import flex.messaging.MessageBroker;
import flex.messaging.messages.AsyncMessage;
import flex.messaging.messages.Message;
import flex.messaging.services.MessageService;
import flex.messaging.services.ServiceAdapter;
import flex.messaging.util.UUIDUtils;

public class CloudServiceAdapter extends ServiceAdapter {
	MonitorClientManager cache = MonitorClientManager.getInstance();
	private static DecimalFormat format= new DecimalFormat("0.00");

	private static int SLEEP_TIME = 10000;
	Random random;
	HistoryDataReader thread;
	private String resourceIP = "";

	public CloudServiceAdapter() {
		random = new Random();
		System.out.println("Adapter initilized");
	}

	public void start() {
		if (thread == null) {
			System.out.println("Adapter started");
			thread = new HistoryDataReader();
			thread.start();
		}
	}

	public void stop() {
		System.out.println("Adapter stopped");
		thread.running = false;
		thread = null;
	}

	private List<HistoryData> generatePoint() {
		// String hostIp = MonitorUtil.getLocalIP();
		System.out.println("begin to get monitor data from server");
		List<HistoryData> dataList = new ArrayList<HistoryData>();
		if (resourceIP != null || !resourceIP.isEmpty()) {
			// Map monitorDatas = (Map) cache.get("172.16.0.86");
			Map monitorDatas = (Map) cache.get(resourceIP);

			HistoryData hd = new HistoryData("" + new Date(),
					Double.valueOf(format.format((Double) monitorDatas.get(Constants.SYS_CPU_USED_PERC)
							* UIConstants.PERC)));
			hd.setName(UIConstants.SYS_CPU_USED_PERC);
			dataList.add(hd);

			hd = new HistoryData("" + new Date(), (Long) monitorDatas
					.get(Constants.SYS_MEM_USED)
					/ UIConstants.MB);
			hd.setName(UIConstants.SYS_MEM_USED + " : "+((Long)monitorDatas.get(Constants.SYS_MEM_TOTAL)/UIConstants.MB));
			dataList.add(hd);

			hd = new HistoryData("" + new Date(), Double.valueOf(format.format((Double) monitorDatas
					.get(Constants.SYS_MEM_USED_PERC))));
			hd.setName(UIConstants.SYS_MEM_USED_PERC);
			dataList.add(hd);

			hd = new HistoryData("" + new Date(), (Long) monitorDatas
					.get(Constants.SYS_FILE_USED));
			hd.setName(UIConstants.SYS_FILE_USED + " : " + monitorDatas.get(Constants.SYS_FILE_TOTAL));
			dataList.add(hd);

			hd = new HistoryData("" + new Date(), Double.valueOf(format.format((Double) monitorDatas
					.get(Constants.SYS_FILE_USED_PERC)
					* UIConstants.PERC)));
			hd.setName(UIConstants.SYS_FILE_USED_PERC);
			dataList.add(hd);

			hd = new HistoryData("" + new Date(), Double.valueOf(format.format((Double) monitorDatas
					.get(Constants.SYS_NETWORK_USED_PERC)
					* UIConstants.PERC)));
			hd.setName(UIConstants.SYS_NETWORK_USED_PERC);
			dataList.add(hd);
		}

		return dataList;
	}

	// private List<HistoryData> generatePoint() {
	// List<HistoryData> dataList = new ArrayList<HistoryData>();
	//	
	// int value = random.nextInt(100);
	// HistoryData data = new HistoryData("" + new Date(), value);
	// data.setName("CPU 1");
	// dataList.add(data);
	//	
	// value = random.nextInt(100);
	// data = new HistoryData("" + new Date(), value);
	// dataList.add(data);
	// data.setName("CPU 2");
	//	
	// value = random.nextInt(100);
	// data = new HistoryData("" + new Date(), value);
	// dataList.add(data);
	// data.setName("CPU 3");
	//	
	// value = random.nextInt(100);
	// data = new HistoryData("" + new Date(), value);
	// dataList.add(data);
	// data.setName("CPU 4");
	//	
	// return dataList;
	// }

	public class HistoryDataReader extends Thread {
		public boolean running = true;

		public void run() {
			String clientId = UUIDUtils.createUUID();
			MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
			while (running) {
				AsyncMessage msg = new AsyncMessage();
				msg.setDestination("CloudInformationServicePush");
				msg.setClientId(clientId);
				List<HistoryData> dataList = generatePoint();
				msg.setMessageId(UUIDUtils.createUUID());
				msg.setBody(dataList);
				msgBroker.routeMessageToService(msg, null);
				try {
					Thread.sleep(SLEEP_TIME);
				} catch (InterruptedException e) {
					System.out.println("Exception");
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public Object invoke(Message msg) {
		String messageBody = msg.getBody().toString();
		if (messageBody.equals("New")) {
			System.out.println("Adapter received new");
			return generatePoint();
		} else if (messageBody.equals("stop")) {
			System.out.println("Adapter Stop");
			this.resourceIP = "";
			stop();
		} else if (messageBody.startsWith("start")) {
			this.resourceIP = messageBody
					.substring(messageBody.indexOf("#") + 1);
			System.out.println("Adapter Start : " + resourceIP);

			start();
		} else {
			System.out.println("Adapter sending message");
			AsyncMessage newMessage = (AsyncMessage) msg;
			MessageService msgService = (MessageService) getDestination()
					.getService();
			msgService.pushMessageToClients(newMessage, true);
		}
		return null;
	}

}